package com.hfjyz.registration.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;

import com.hfjyz.registration.command.AdminLoginCommand;
import com.hfjyz.registration.command.AdminModifyCommand;
import com.hfjyz.registration.command.AdmissionCommand;
import com.hfjyz.registration.command.ModifyPasswordCommand;
import com.hfjyz.registration.command.RegistCommand;
import com.hfjyz.registration.command.ScoreSearchCommand;
import com.hfjyz.registration.command.SignUpPersonSearchCommand;
import com.hfjyz.registration.command.StatusSearchCommand;
import com.hfjyz.registration.command.VerifyCommand;
import com.hfjyz.registration.dao.AdminDao;
import com.hfjyz.registration.dao.AdmissionDao;
import com.hfjyz.registration.dao.ApplyDao;
import com.hfjyz.registration.dao.CityDao;
import com.hfjyz.registration.dao.DepartDao;
import com.hfjyz.registration.dao.MasterDao;
import com.hfjyz.registration.dao.OfficeDao;
import com.hfjyz.registration.dao.OrderInfoDao;
import com.hfjyz.registration.dao.UserDao;
import com.hfjyz.registration.model.Admin;
import com.hfjyz.registration.model.Admission;
import com.hfjyz.registration.model.Apply;
import com.hfjyz.registration.model.ApplyPK;
import com.hfjyz.registration.model.City;
import com.hfjyz.registration.model.Depart;
import com.hfjyz.registration.model.Exam;
import com.hfjyz.registration.model.Office;
import com.hfjyz.registration.model.OrderInfo;
import com.hfjyz.registration.model.User;
import com.hfjyz.registration.util.CryptUtil;

public class RegistServiceImpl extends AbstractServiceImpl implements
		RegistService {

	private UserDao userDao;
	private DepartDao departDao;
	private OfficeDao officeDao;
	private CityDao cityDao;
	private ApplyDao applyDao;
	private OrderInfoDao orderInfoDao;
	private MasterDao masterDao;
	private AdminDao adminDao;
	private AdmissionDao admissionDao;

	@Override
	@Transactional
	public void add(RegistCommand object) throws Exception {
		User user = new User();
		user.setName(object.getName());
		user.setPassword(CryptUtil.encrypt(object.getPassword()));
		user.setIdCardNo(object.getIdCardNo());
		user.setExamId(object.getExam().getId());
		user.setSex(Integer.parseInt(object.getSexCode()));
		user.setNationCode(Integer.parseInt(object.getNationCode()));
		user.setHomeTown(object.getHomeTown());
		user.setBirthdayMonth(object.getBirthdayMonth());
		user.setBirthdayYear(object.getBirthdayYear());
		user.setPoliticalCode(Integer.parseInt(object.getPoliticalCode()));
		user.setIdentity(Integer.parseInt(object.getIdentity()));
		user.setMarried(Integer.parseInt(object.getIsMarried()));
		user.setDegree(object.getDegree());
		user.setGraduateSchool(object.getUserSchool());
		user.setGraduateYear(Integer.parseInt(object.getGraduateYear()));
		user.setGraduateMonth(Integer.parseInt(object.getGraduateMonth()));
		user.setWorkyears(Integer.valueOf(object.getWorkYears()));
		user.setMajor(object.getUserMajor());
		user.setComputerSkill(object.getComputerSkill());
		user.setLanguageSkill(object.getLanguageSkill());
		user.setTelephone(object.getTelephone());
		user.setHeight(Integer.parseInt(object.getHeight()));
		user.setTrainingExp(object.getTrainingExp());
		user.setWorkExp(object.getWorkExp());
		user.setSocialRel(object.getSocialRel());
		user.setPhoto(object.getPhoto());
		Integer userId = object.getUserId();
		String reason = "";
		if (object.getUserId() == null) {
			userId = getUserDao().add(user);
			object.setUserId(userId);
		} else {
			user.setId(object.getUserId());
			getUserDao().update(user);
			Apply apply = getApplyDao().get(userId, object.getExam().getId());
			if (apply != null) {
				getApplyDao().delete(apply);
			}
		}
		Apply apply = new Apply();
		ApplyPK applyPk = new ApplyPK();
		applyPk.setUserid(userId);
		applyPk.setOfficeid(Integer.valueOf(object.getApplyPostId()));
		apply.setId(applyPk);
		apply.setState(0);
		apply.setReason(reason);
		apply.setExamId(Integer.valueOf(object.getRegistExamCode()));
		getApplyDao().add(apply);
	}

	@Override
	public List<Depart> listDepart(Exam exam) throws Exception {
		return departDao.listByExam(exam);
	}

	@Override
	public List<Depart> getDepartByExamId(String examId) throws Exception {
		return departDao.getDepartById(examId);
	}

	@Override
	public List<Office> listOffice(Exam exam) throws Exception {
		return officeDao.listByExam(exam);
	}
	
	@Override
	public List<Office> getOfficeByExamId(String examId) throws Exception {
		return officeDao.getOfficeById(examId);
	}

	@Override
	public List<City> listCity() throws Exception {
		return cityDao.listAll();
	}

	// @Override
	// public List<Exam> listExam() throws Exception {
	// return examDao.listAll();
	// }

	@Override
	public List<Apply> listApplyUser(SignUpPersonSearchCommand cmd)
			throws Exception {
		return applyDao.list(cmd);
	}

	@Override
	public List<User> findUser(String userName) throws Exception {
		return userDao.findUserName(userName);
	}

	@Override
	public User findIdCardNo(String idCardNo, Integer examId) throws Exception {
		return userDao.getByIdCardNo(idCardNo, examId);
	}

	// @Override
	// public Apply getApply(Integer userId, Integer officeId) throws Exception
	// {
	// return applyDao.get(userId, officeId);
	// }

	@Override
	public Apply getApply(Integer userId, Integer examId) throws Exception {
		return applyDao.get(userId, examId);
	}

	@Override
	public Office getOffice(Integer officeId) throws Exception {
		return officeDao.get(officeId);
	}

	/**
	 * @return the userDao
	 */
	public UserDao getUserDao() {
		return userDao;
	}

	/**
	 * @param userDao
	 *            the userDao to set
	 */
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * @return the departDao
	 */
	public DepartDao getDepartDao() {
		return departDao;
	}

	/**
	 * @param departDao
	 *            the departDao to set
	 */
	public void setDepartDao(DepartDao departDao) {
		this.departDao = departDao;
	}

	/**
	 * @return the officeDao
	 */
	public OfficeDao getOfficeDao() {
		return officeDao;
	}

	/**
	 * @param officeDao
	 *            the officeDao to set
	 */
	public void setOfficeDao(OfficeDao officeDao) {
		this.officeDao = officeDao;
	}

	/**
	 * @return the cityDao
	 */
	public CityDao getCityDao() {
		return cityDao;
	}

	/**
	 * @param cityDao
	 *            the cityDao to set
	 */
	public void setCityDao(CityDao cityDao) {
		this.cityDao = cityDao;
	}

	/**
	 * @return the applyDao
	 */
	public ApplyDao getApplyDao() {
		return applyDao;
	}

	/**
	 * @param applyDao
	 *            the applyDao to set
	 */
	public void setApplyDao(ApplyDao applyDao) {
		this.applyDao = applyDao;
	}

	/**
	 * @return the masterDao
	 */
	public MasterDao getMasterDao() {
		return masterDao;
	}

	/**
	 * @param masterDao
	 *            the masterDao to set
	 */
	public void setMasterDao(MasterDao masterDao) {
		this.masterDao = masterDao;
	}

	/**
	 * @return the adminDao
	 */
	public AdminDao getAdminDao() {
		return adminDao;
	}

	/**
	 * @param adminDao
	 *            the adminDao to set
	 */
	public void setAdminDao(AdminDao adminDao) {
		this.adminDao = adminDao;
	}

	/**
	 * @return the admissionDao
	 */
	public AdmissionDao getAdmissionDao() {
		return admissionDao;
	}

	/**
	 * @param admissionDao
	 *            the admissionDao to set
	 */
	public void setAdmissionDao(AdmissionDao admissionDao) {
		this.admissionDao = admissionDao;
	}

	public OrderInfoDao getOrderInfoDao() {
		return orderInfoDao;
	}

	public void setOrderInfoDao(OrderInfoDao orderInfoDao) {
		this.orderInfoDao = orderInfoDao;
	}

	@Override
	public void modifyPassword(ModifyPasswordCommand cmd, BindException errors)
			throws Exception {
		User u = userDao.getByIdCardNo(cmd.getIdCardNo(), cmd.getExam().getId());
		if (u == null) {
			errors.rejectValue("idCardNoError", "required.idCardNoError",
					"身份证号不正确!");
			return;
		}
		String encryPass = CryptUtil.encrypt(cmd.getOldPassword());
		if (!encryPass.equals(u.getPassword())) {
			errors.rejectValue("oldPassword", "required.oldPassword", "旧密码不正确!");
			return;
		}
		u.setPassword(CryptUtil.encrypt(cmd.getPassword()));
		userDao.update(u);

	}

	@Override
	public void searchStatus(StatusSearchCommand cmd, BindException errors)
			throws Exception {
		User u = userDao.getByIdCardNo(cmd.getIdCardNo(), cmd.getExam().getId());
		if (u == null) {
			errors.rejectValue("idCardNo", "required.idCardNo", "身份证号不正确!");
			return;
		}
		if (!CryptUtil.encrypt(cmd.getPassword()).equals(u.getPassword())) {
			errors.rejectValue("password", "required.password", "密码不正确!");
			return;
		}
		cmd.setUser(u);
		List<Apply> applyList = applyDao.findApplyInfo(u.getId(), cmd.getExam()
				.getId());
		if (applyList == null || applyList.isEmpty()) {
			errors.rejectValue("idCardNo", "required.apply", "找不到该考生的报名信息");
			return;
		}
		Apply a = applyList.get(0);
		cmd.setApply(a);
		
		OrderInfo order = orderInfoDao.findByUserIdAndExamId(u.getId(), cmd.getExam()
				.getId());
		if (order != null) {
			cmd.setOrderState(order.getOrderState());
		}
	}

	@Override
	public void initVerify(VerifyCommand cmd) throws Exception {
		User user = userDao.get(cmd.getUserId());
		if (user == null) {
			throw new Exception("选择的考生不存在！");
		}
		cmd.setUser(user);
		List<Apply> applyList = applyDao.findApplyInfo(user.getId(), cmd
				.getExam().getId());
		if (applyList == null || applyList.isEmpty()) {
			throw new Exception("找不到该考生的报名信息");
		}
		Apply a = applyList.get(0);
		cmd.setApply(a);
		cmd.setVerifyReason(a.getReason());
		cmd.setVerifyState(String.valueOf(a.getState()));
	}

	@Override
	public void verify(Apply apply) throws Exception {
		applyDao.update(apply);
	}

	@Override
	public void adminLogin(AdminLoginCommand cmd, BindException errors)
			throws Exception {
		String adminId = cmd.getAdminId();
		String password = cmd.getAdminPassword();
		Admin admin = adminDao.get(adminId);
		if (admin == null) {
			errors.rejectValue("adminId", "adminId.error", "管理员帐号不存在！");
			return;
		}
		String encryPass = CryptUtil.encrypt(password);
		if (!encryPass.equals(admin.getPassword())) {
			errors.rejectValue("adminPassword", "password.error", "密码不正确！");
			return;
		}
	}

	@Override
	public void modifyAdminPassword(AdminModifyCommand cmd, BindException errors)
			throws Exception {
		Admin admin = adminDao.get(cmd.getAdminId());
		if (admin == null) {
			errors.rejectValue("adminId", "adminId.error", "管理员帐号不存在!");
			return;
		}
		String encryPass = CryptUtil.encrypt(cmd.getOldPassword());
		if (!encryPass.equals(admin.getPassword())) {
			errors.rejectValue("oldPassword", "oldPassword.error", "旧密码不正确!");
			return;
		}
		admin.setPassword(CryptUtil.encrypt(cmd.getPassword()));
		adminDao.update(admin);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Map initAdminEdit(AdminModifyCommand cmd, Errors errors)
			throws Exception {
		Admin admin = adminDao.getInfoById(cmd.getId());
		cmd.setAdminId(admin.getAdministratorId());
		return null;
	}

	@Override
	public void printAdmission(AdmissionCommand cmd, BindException errors)
			throws Exception {
		Exam exam = cmd.getExam();
		Date now = new Date();

		Date start = exam.getAdmissionPrintStart() == null ? now : exam
				.getAdmissionPrintStart();
		Date end = exam.getAdmissionPrintEnd() == null ? now : exam
				.getAdmissionPrintEnd();
		if (now.before(start) || now.after(end)) {
			throw new Exception("当前时间段不在打印时间内，请在规定时间段内打印笔试准考证！");
		}

		Admission admission = admissionDao.getByUid(cmd.getUser().getId(), exam.getId());
		if (admission == null) {
			throw new Exception("管理员还未分配座位，请等待座位分配完毕，再打印准考证");
		}
		cmd.setExam(exam);
		cmd.setAdmission(admission);

		admission.setPrintFlg(true);
		admissionDao.update(admission);
	}

	@Override
	public void printApply(Integer userId, Integer examId) throws Exception {
		Apply apply = applyDao.get(userId, examId);
		apply.setPrintFlg(true);
		applyDao.update(apply);
	}

	@Override
	public void searchScore(ScoreSearchCommand cmd, BindException errors)
			throws Exception {
		User u = userDao.getByIdCardNo(cmd.getIdCardNo(), cmd.getExam().getId());
		if (u == null) {
			errors.rejectValue("idCardNo", "required.idCardNo", "身份证号不正确!");
			return;
		}
		if (!cmd.isAdminSearch()) {
			if (!CryptUtil.encrypt(cmd.getPassword()).equals(u.getPassword())) {
				errors.rejectValue("password", "required.password", "密码不正确!");
				return;
			}
		}
		cmd.setUser(u);
		SignUpPersonSearchCommand condition = new SignUpPersonSearchCommand();
		condition.setExam(cmd.getExam());
		condition.setIdCardNo(cmd.getIdCardNo());
		List<Apply> applyList = applyDao.list(condition);
		if (applyList == null || applyList.isEmpty()
				|| applyList.get(0).getAdmission() == null
				|| applyList.get(0).getAdmission().getScore() == null) {
			errors.rejectValue("idCardNo", "required.apply", "笔试成绩未找到");
			return;
		}
		Apply a = applyList.get(0);
		cmd.setApply(a);
	}
}
